package face.util;

import java.nio.IntBuffer;
import java.util.List;

import org.bytedeco.javacpp.DoublePointer;
import org.bytedeco.javacpp.IntPointer;
import org.bytedeco.javacpp.opencv_core;
import org.bytedeco.javacpp.opencv_core.Mat;
import org.bytedeco.javacpp.opencv_core.MatVector;
import org.bytedeco.javacpp.opencv_core.Rect;
import org.bytedeco.javacpp.opencv_core.RectVector;
import org.bytedeco.javacpp.opencv_core.Size;
import org.bytedeco.javacpp.opencv_face.FaceRecognizer;
import org.bytedeco.javacpp.opencv_face.LBPHFaceRecognizer;

import com.google.common.collect.Lists;

import org.bytedeco.javacpp.opencv_imgproc;

import face.entity.Face;

/**
 * 进行人员识别 -- 要更换人脸识别的引擎，LHPH方便xml更新
 * @author ShiQiang
 *
 */
public class IdentityPeople {
	
	static FaceRecognizer faceRecognizer = LBPHFaceRecognizer.create();
  //EigenFaceRecognizer.create();
//    FaceRecognizer faceRecognizer = createEigenFaceRecognizer();
//    FaceRecognizer faceRecognizer = LBPHFaceRecognizer.create();
//    FaceRecognizer faceRecognizer = EigenFaceRecognizer.create();
	
	public static List<Face> findPeople(Mat oriFrame,RectVector faces) {
	    
		Mat imageGray = FaceAndEyeToos.doColorHist(oriFrame);
		getTainFile(faceRecognizer); 
		Mat saveFace = null; 
		List<Face> result = Lists.newArrayList();
		for (Rect rect : faces.get()) {  
			
			saveFace = new Mat(imageGray, rect); 
			opencv_imgproc.resize(saveFace, saveFace, new Size(Common.faceWidth, Common.faceHeight));
			
			//人脸对齐
			
			IntPointer label = new IntPointer(4);
			DoublePointer confidence = new DoublePointer(8);
			faceRecognizer.predict(saveFace, label, confidence);
			
			int predictedLabel = label.get(0);
			System.out.println(predictedLabel);
			if(predictedLabel != 0){
				//查找到当前人员信息直接返回
				result.add(FaceList.getFace(predictedLabel-1)); 
			}else{ 
				continue;
			}
			
		}
		return result;
	}
	
	/**
	 * 人脸图片添加并训练
	 */
	public static void train(){  
		int faceSize = FaceList.getFaceFiles().size();
	    MatVector images = new MatVector(faceSize+1);
	    Mat labels = new Mat(faceSize+1, 1,opencv_core.CV_32SC1);
	    IntBuffer labelsBuf = labels.createBuffer();
	    labelsBuf.put(0,0); 
	    images.put(0,FaceList.getFace(PathUtil.getFilePath(Common.invalidFace)));
	    for (int i = 1; i < faceSize+1; i++) {
	        Face p = FaceList.getFaceFiles().get(i-1); 
	        images.put(i, p.getFaceMat());
	        labelsBuf.put(i, i); 
	    }  
	    
	    faceRecognizer.train(images, labels);  
	    saveTainFile(faceRecognizer);
	}
	public static void main(String[] args) {
		train();
	}
	//确保读取和写入只有一个进行再做
	public static void getTainFile(FaceRecognizer faceRecognizer){
		 synchronized(IdentityPeople.class){
			 faceRecognizer.read(Common.trainModelPath);
		 }
	}
	
	public static void saveTainFile(FaceRecognizer faceRecognizer){
		 synchronized(IdentityPeople.class){
			 faceRecognizer.save(Common.trainModelPath);
		 }
	}
	
	/**
	 * 更新识别模型 - 目前有问题
	 * @param img
	 */
	public static void updateModel(Mat img){
		int index= FaceList.getFaceFiles().size()+2;
		MatVector images = new MatVector(index);
	    Mat labels = new Mat(index, 1,opencv_core.CV_32SC1);
	    IntBuffer labelsBuf = labels.createBuffer();  
        images.put(index,img);
        labelsBuf.put(index,index);  
		faceRecognizer.update(images, labels);
	}
}